<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title>正则表达式</title>
	</head>
	<body>
		<a href="###" class="zb qq">超链接1</a>
		<p class="zb">我是p标签</p>
		<strong class="ww zb qq">strong标签</strong>
		<div class="zbzb">div标签</div>
	</body>
</html>
<script type="text/javascript">
	/*
	 * 1.不单单是针对html5开发的技术,安卓,ios,php,java,都可以用到它
	 * 2.通过正则表达式,可以对整体字符串,进行截取,替换,验证,模糊搜索,使用非常简单
	 * 3.是一门新的语法
	 * 4.正则表达式可以搜索
	 */
	//引入
	var str = "asgsdg123";
	for(var i = 0;i < str.length;i++){
		if(str[i] >= "0" && str[i] <= "9"){
			console.log("有数字");
			break;
		}
	}
	if(i == str.length){
		console.log("没有数字");
	}
	//正则
	var reg = /\d/;
	console.log(reg.test(str));
	
	/*
	 * 正则表达式语法:
	 * 	字符:
	 * 		1.普通字符
	 * 		2.元字符,有特殊的含义,(如\d:代表一个数字,*,+,?等)
	 */
	/*
	 * js中如何创建正则表达式对象:
	 *   1.复杂方式:
	 * 		new RegExp("正则表达式(描述的条件)","属性")
	 * 			*两个参数都是字符串类型
	 * 	 		属性:
	 * 				i:忽略大小写
	 * 				m:
	 * 				g:
	 * 	自身优势:可以传入变量,进行变量的拼接
	 * 
	 * 	 2.简单写法:
	 * 		/正则条件/属性
	 * 	自身优势:简单
	 * 
	 * /pattern/属性
	 */
	var str = "我们是H0711班";
//	var reg = new RegExp("h","i");
	var reg = /h/i;
	console.log(reg.test(str));
	
	/*
	 * 正则表达式函数
	 * 	1.reg.test(字符串)
	 * 		返回值:boolean:true/false
	 * 		作用:对字符串进行验证
	 */
	/*
	 *元字符:
	 * 	\d:代表一个数字
	 * 	\s:代表一个空白符(\n,\r,\t,空格)
	 * 	\w:代表一个字符(字母,数字,下划线),不包含特殊字符和汉字
	 * 反义字符(对上边的意思取反)
	 * 	\D:代表一个非数字
	 * 	\S:代表一个非空白符
	 * 	\W:代表一个非字符
	 * 	.:代表一个除换行符(\n,\r,\t)以外的字符
	 * **************************************
	 * 量词:
	 * 	*: >= 0    eg: \w\d*
	 * 	+: >= 1
	 * 	?: 0|1
	 * 	{n}:个数为n个
	 * 	{n,m}: 个数[n,m]之间
	 * 	{n,}: 个数在>=n上
	 * 	
	 * * == {0,}
	 * + == {1,}
	 * ? == {0,1}
	 * **************************************
	 * 匹配字符:
	 * [345]:代表一个或3或4或5的字符
	 * [^345]:代表一个除3,4,5之外的字符
	 * **************************************
	 * 连字符:表示一个范围
	 * 	[a-z]:小写字母的一个
	 * 	[A-Z]:大写字母的一个
	 * 	[0-9]:代表一个数字 \d
	 * 	[\u4e00-\u9fa5]:代表一个汉字
	 * **************************************
	 * 定位符:
	 * 	^:指代整个字符串的开始位置
	 * 	$:指代整个字符串的结束位置
	 * 	\b:单词分界 eg:\bstudent\b
	 * **************************************
	 * 分组符:
	 * 把用小括号包含起来的内容看成一个整体
	 * 	(ab){2} == abab
	 * 分支符:
	 * 	|:条件的并集
	 * 	a|b|c
	 * 
	 * 
	 * 
	 */
	var str = "今年是2017年_ ";
//	var reg = /今年/;
//	var reg = /\d\d/;
//	var reg = /\w/;
	var reg = /\s/;
	console.log(reg.test(str));
	/*
	 * 量词的例子
	 */
	var str = "nimen zhenshi tai 6666le";
	//是否有连续的三个空白符
//	var reg = /\s{3}/;
//	var reg = /\d{5}/;
	var reg = /\w\d{4}/;
	console.log(reg.test(str));
	
	//手机号
	var reg = /^1[3578]\d{9}$/;
	var str = "15637212333";
	console.log(reg.test(str));
	
	var str = "abc 4564 df";
	var reg = /[456]{4}/;
	var reg = /[a-z]{4}/;
	console.log(reg.test(str));
	
	//练习2
	var arr = ["三国演义.txt","金瓶梅.doc","chinaDaily.doc","TomAndJerry.pdf"];
	var aArr = [];
	for(var i = 0;i <arr.length;i++){
		var str = arr[i];
		if(/[\u4e00-\u9fa5]+\./.test(str)){
			aArr.push(str);
		}
	}
	console.log(aArr);
	
	
	/*
	 * 定位符:
	 */
	var str = "i love you";
	var reg = /^i/;
	console.log(reg.test(str));
	//找到后缀为.doc的图书
	var newArr = [];
	for(var i = 0;i <arr.length;i++){
		var str = arr[i];
		if(/\.doc$/.test(str)){
			newArr.push(str);
		}
	}
	console.log(newArr);
	
	var str = "student is future of china,stustu";
	var reg = /\bstu\b/;
//	var reg = /\bstu/;
	console.log(reg.test(str));
	//注意:
	var str = "today is friday,tomcat";
	//整个字符串是否为t
	var reg = /^t$/;
	console.log(reg.test(str));
	
	//兼容低版本(通过类名获取元素)
	function getByClassName(classStr){
		var aEles = document.getElementsByTagName("*");
		var arr = [];
		for(var i = 0;i < aEles.length;i++){
			var str = aEles[i].className;
			var reg = new RegExp("\\b" + classStr + "\\b");
			if(reg.test(str)){
				arr.push(aEles[i]);
			}
		}
		return arr;
	}
	console.log(getByClassName("zb"));
	
	/*
	 * 字符串匹配:
	 *	 字符串函数
	 * 		match(参数):
	 * 			参数:需匹配的字符串/正则表达式对象
	 * 			返回值:数组/null
	 * 
	 */
	var str = "我们很开心,我们很快乐";
//	var ret = str.match("我们");
	//g:全局匹配
	var reg = /我们/g;
	var ret = str.match(reg);
	console.log(ret,ret.length);
	var str = "abc12xf321";
	var reg = /[a-z]{2}\d{2}/g;
	console.log(str.match(reg));
	//拓展:匹配的贪婪与懒惰
	var str = "abc12345abc";
//	var reg = /\d+/;
	//变懒惰 +?(尽可能的少取)
	var reg = /\d+?/;
	var ret = str.match(reg);
	console.log(ret);
	
	//2.使用正则函数exec进行匹配
	/*
	 * 语法:
	 * 	exec(字符串)
	 * 		当正则表达式,加g和不加g在结合exec使用时的区别:
	 * 			不加g时,都是从字符串的最左边开始匹配,而加上g时,第二次使用,会在上一次的基础上,继续往右匹配
	 */
	var str = "friday is comming,friday raining";
	var reg = /friday/g;
	var arr = reg.exec(str);
	var arr2 = reg.exec(str);
	console.log(arr,arr2);
	
	//分组符
	var str = "abab aabb ccff abcabc abab";
	/*
	 * 分组:默认捕获型分组,会把写到分组中的内容捕获下来,放到结果数组中
	 * 非捕获型分组(?:)
	 * 
	 * 分组中结合全局匹配g使用时,不需要考虑捕获型分组
	 */
//	var reg = /(ab){2}/;
	var reg = /(ab){2}/g;
//	var reg = /(?:ab){2}/;
	console.log(str.match(reg));
	/*
	 * 分组的正向预测
	 * pattern(?=)
	 * 反向预测(?<=pattern),不太支持
	 */
	var str = "中国人中国龙";
	var reg = /中国(?=人)/;
	console.log(str.match(reg));
	/*
	 * 设置分组后,分组又会自动编号
	 * 每当出现一个分组时,都会给该分组进行编号,编号从1开始,可以使用\编号,相当于分组中匹配出来的内容
	 */
	var str = "abcdd11eegf";
	var reg = /(\w)(\d)\2/g;
	console.log(str.match(reg));
	
	//分支符
	//条件1|条件2,当条件1跟条件2有重叠时,从左到右,满足条件1,条件2就会被短路
	var str = "abcdef";
//	var reg = /abc|def/g;
	var reg = /abcd|def/g;
	console.log(str.match(reg));
	
	//判断是否为手机号
	var reg = /^1(3|5|7|8)\d{9}$/;
	var str = "15637212333";
	console.log(reg.test(str));
	
	/*
	 * 字符串函数
	 * 	search():
	 * 	获取检索字符串的下标
	 * 		参数:字符串/正则表达式
	 * 		返回值:-1,下标
	 * 		可以进行模糊搜索
	 * 	replace(参数1,参数2):
	 * 		参数1:被替换的字符串/正则表达式
	 * 		参数2:替换字符串/函数
	 * 		返回值:更改之后的字符串,原字符串不做改变
	 */
	var str = "abc1234def";
	var ret = str.search("0");
	//自身优势
	var ret = str.search(/\d/g);
	console.log(ret);
	
	/*
	 * replace()
	 */
	var str = "今天很凉爽,今天要写周报";
//	var ret = str.replace("今天","明天");
//	var ret = str.replace(/今天/g,"明天");
	var ret = str.replace(/今天/g,function(v){
		console.log(v.slice(1)+"下");
		return v.slice(1)+"下";
	})
	console.log(ret,str);	
	
	//练习:trim(),兼容性不好,
	String.prototype.trim = function(){
		//this就是需要去除空格的string
		return	this.replace(/^\s+|\s+$/g,"");
	};
	var str = "   aaa   bbb  ";
	console.log(str);
	console.log(str.trim());
	
	//敏感词练习
	var str = "去你学校,去你妹的,去你大爷,骑马的汉子";
	var arr = ["妈蛋","大爷","妹的"];
	var reg = /去你[\u4e00-\u9fa5]+[^\w\d]/g;
	str = str.replace(reg,function(v){
		console.log(v);
		var index = arr.indexOf(v.slice(2,v.length - 1));
		if(index != -1){
			var zb = "";
			for(var i = 0;i < arr[index].length;i++){
				zb += "*";
			}
			return "去你" + zb + v.slice(v.length - 1);
		}
		return v;
	});
	console.log(str);
	
	//属性m的讲解,多结合定位符使用
	//加上m,判断的标准不再是整个字符串,而是当前行
	var str = "mo\nmo";
	console.log(str);
	var reg = /^mo$/m;
	console.log(reg.test(str));
	
	//转义字符
	/*
	 * 在正则中,让元字符作为内容呈现,需要转义
	 * *,?,.,(,),{,},[,],/,$,^,|等
	 */
	
	//1.判断是否为合法的QQ号,最少5位,最多11位
	var reg = /^[1-9]\d{4,10}$/;
	var str = "1397072427";
	console.log("QQ号:"+reg.test(str));
	//2.判断输入的是不是http://开头的合法链接
	var str = "http://www.lanou3g.com";
	var reg = /^https?:\/\/www\.[a-z\d]+\.(com|top|edu|org)$/;
	console.log(reg.test(str));
	//3.封装首字母大写功能
	var str = "lover day is coming please play game with your girlfriend";
	String.prototype.toCapital = function(){
		var reg = /\b([a-z]|[A-Z])+\b/g;
		return this.replace(reg,function(word){
			return word.charAt().toUpperCase() + word.slice(1);
		})
	}
	console.log(str.toCapital());
	
	
</script>








